using System;
using System.Collections.Generic;
using GameFramework.Business;
using GameFramework.Extensions;
using GameFramework.Fsm;
using GameFramework.Update;

namespace GameFramework.Procedure.Fsm
{
    /// <summary>
    /// 基于有限状态机实现的流程抽象类
    /// </summary>
    public abstract class AFsmProcedure : AFsmState, IProcedure
    {
        public override void OnEnter(IFsm fsm)
        {
            if (m_ViewControllers == null)
            {
                m_ViewControllers = new List<IViewController>();
                OnAddControllers(m_ViewControllers);
                
                foreach (var controller in m_ViewControllers)
                {
                    // ReSharper disable once SuspiciousTypeConversion.Global
                    if (controller is IUpdate update)
                        m_Updates.Add(update);
                }
            }

            var container = CatLib.App.That;
            
            foreach (var controller in m_ViewControllers)
            {
                container.Inject(controller);
                
                try
                {
                    controller.Initialize();
                }
                catch (Exception e)
                {
                    Log.Exception(e);
                }
            }
        }

        public override void OnLeave(IFsm fsm)
        {
            for (var index = m_ViewControllers.Count - 1; index >= 0; --index)
            {
                var controller = m_ViewControllers[index];
                
                try
                {
                    controller.Dispose();
                }
                catch (Exception e)
                {
                    Log.Exception(e);
                }
            }
        }

        public override void OnUpdate(IFsm fsm, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(fsm, elapseSeconds, realElapseSeconds);

            foreach (var update in m_Updates)
            {
                try
                {
                    update.OnUpdate(elapseSeconds, realElapseSeconds);
                }
                catch (Exception e)
                {
                    Log.Exception(e);
                }
            }
        }

        /// <summary>
        /// 派生类在该方法中添加所需的视图控制器
        /// </summary>
        protected virtual void OnAddControllers(List<IViewController> controllers)
        {
        }

        private List<IViewController> m_ViewControllers;
        private readonly List<IUpdate> m_Updates = new();
    }
}